package com.moons.settings.config;

import android.content.Context;
import android.util.Log;

import java.lang.ref.WeakReference;
import java.util.Timer;
import java.util.TimerTask;

public class ARHidTransfer{
    private static final String TAG = ARHidTransfer.class.getSimpleName();
    private WeakReference<Context> mWeakContext = null;

    private ARUsbTransfer arUsbTransfer;

    private boolean isOpen;

    private Timer timer_heart;
    private boolean bHeart = false;

    public interface StatusCallback{
        void onStatusChange(ARCommon.LOG_MSG_TYPE msg_type,String msg,int process);
    }
    private StatusCallback statusCallback = null;

    public void addCallback(StatusCallback callback){
        statusCallback = callback;
    }
    public void removeCallback(){
        statusCallback = null;
    }

    private void statusChange(ARCommon.LOG_MSG_TYPE msg_type,String msg,int process){
        if(statusCallback==null)
            return;
        statusCallback.onStatusChange(msg_type,msg,process);
    }

    public interface FaceDetectCallback{
        void onDetectFace(String data);
    }
    private FaceDetectCallback faceDetectCallback = null;
    public void addFaceDetectCallback(FaceDetectCallback callback){ faceDetectCallback = callback;}
    public FaceDetectCallback getFaceDetectCallback(){ return  faceDetectCallback;}
    public void removeFaceDetectCallback(){ faceDetectCallback = null;}
    private void onFaceDetect(String s){
        if(faceDetectCallback==null)
            return;
        faceDetectCallback.onDetectFace(s);
    }

    private static  ARHidTransfer hidTransfer = null;

    public static ARHidTransfer instance(){
        if(hidTransfer==null)
            hidTransfer = new ARHidTransfer();
        Log.d(TAG,"====hidTransfer======"+hidTransfer);

        return hidTransfer;
    }

    private ARHidTransfer(){
        isOpen = false;
    }

    public void init(Context ctx){
        mWeakContext = new WeakReference<Context>(ctx);
        arUsbTransfer = new ARUsbTransfer(mWeakContext.get());
        arUsbTransfer.addCallback(usbstatusCallback);
    }

    public void register(){
        arUsbTransfer.register();
    }

    public void unregister(){
        arUsbTransfer.unregister();
    }

    public static boolean hasArUvc(Context ctx){
        return ARUsbTransfer.hasArUvc(ctx);
    }

    public boolean Open(){
        if(isOpen)
            return true;
        return arUsbTransfer.Open();
    }

    public void Close(){
        isOpen = false;
        arUsbTransfer.Close();
    }

    public void TransFirmware(String filename){
        arUsbTransfer.TransFirmware(filename);
    }

    public void TransFile(String filename){
        arUsbTransfer.TransFile(filename);
    }

    public boolean SendUCmd(String ucmd){
        return arUsbTransfer.SendUCmd(ucmd);
    }

    public boolean startHeart(){
        boolean ret = arUsbTransfer.sendHeartCmd(1);
        if(ret){
            setHeart(true);
        }
        return ret;
    }

    public boolean stopHeart(){
        boolean ret = arUsbTransfer.sendHeartCmd(0);
        if(ret){
            setHeart(false);
        }
        return ret;
    }

    public boolean rebootUVC(){
        return arUsbTransfer.sendHeartCmd(3);
    }

    public boolean sendHeart(){
        return arUsbTransfer.sendHeartCmd(2);
    }

    public void getUVCInfo(){
        arUsbTransfer.SendReadDevInfoCmd();
    }

    public boolean sendArstackConfig(int cmd,byte[] data){
        return arUsbTransfer.sendArstackConfig(cmd,data);
    }

    private ARUsbTransfer.StatusCallback usbstatusCallback = new ARUsbTransfer.StatusCallback() {
        @Override
        public void onStatusChange(ARUsbTransfer.LOG_MSG_TYPE log_msg_type, String s, int i) {
            ARCommon.LOG_MSG_TYPE msg_type = ARCommon.LOG_MSG_TYPE.values()[log_msg_type.ordinal()];
            //Log.w(TAG, "onStatusChange: "+s);
            switch (msg_type){
                case HID_OPEN_STATUS:
                    if(s.contains("success")){
                        isOpen = true;
                        ARHidTransfer.instance().getUVCInfo();
                    }
                    break;
                case HID_HERT_RET:
                    if(s.equals("heart")){
                        Log.d(TAG, "run: recive heart");
                        bHeart = true;
                    }
                    break;
                case HID_CONF_RET:{
                    if(s.contains("feature")||s.contains("config")||(s.contains("faces")&&s.contains("null"))){
                        //Log.d(TAG, "feature data: len="+s.length());
                        onFaceDetect(s);
                    }
                }
                    break;
                default:
                    break;
            }
            statusChange(msg_type,s,i);
        }
    };

    private void setHeart(final boolean bstart){
        if(bstart){
            bHeart = true;
            timer_heart = new Timer();
            timer_heart.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    if(bHeart){
                        bHeart = false;
                        Log.d(TAG, "run: send heart");
                        if(!sendHeart()){
                            bHeart = true;
                        }
                    }
                    else{
                        Log.e(TAG, "run: heart fail");
                        stopHeart();
                        //rebootUVC();
                    }
                }
            }, 0, 5000);
        }
        else{
            if(timer_heart!=null) {
                timer_heart.cancel();
                timer_heart = null;
            }
        }
    }
}
